iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 7
0

本系列文章經過重新編排和擴充,已出書為ECMAScript關鍵30天。原始文章因當時準備時程緊迫,多少有些許錯誤。為了避免造成讀者的困擾,以及配合書籍的內容規劃,將會陸續更新本系列文章。
本篇文章在 2021/11/5 已更新。

今天介紹的是關於物件的處理,包括重要的特性和方法的擴充。

重要特性

變數名稱填入賦值

當填入變數名稱,其名稱會成為屬性名稱,而變數的值成為屬性值。

let name = 'ECMAScript 關鍵 30 天';
let author = 'Yuri';

const data = { name, author };
// { name: "ECMAScript 關鍵 30 天", lead: "Yuri"}

簡化新增方法屬性

除了可以像上面一樣變數賦值,也可直接在屬性名稱後加(){}新增函式。

function sayHi() {
    console.log('Say Hi! ');
}

const data1 = { name, lead, sayHi };
const data2 = {
    sayBye() {
        console.log('Say Bye! ');
    },
};

動態屬性名稱

屬性名稱以[variable]中括號包覆變數的形式,動態決定屬性名稱。

const platforms = ['FB', 'IG', 'LINE'];
let myObject = {};

platforms.map((name, index) => (myObject[`sns_${s}`] = index));

console.log(myObject);
// {
//   sns_FB: 0
//   sns_IG: 1
//   sns_LINE: 2
// }

物件的解構賦值(Destructuring Assignment)

解構賦值是ES2015的新特性,只需要一行表達式,就可以把物件中的成員個別指派到跟鍵相同的變數,方便後續的存取。寫法上是將等號左邊的變數排列在物件中,等號右邊則是目標物件。

const bookData = {
    name: 'ECMAScript 關鍵 30 天',
    author: 'Yuri',
    publish: '博碩',
};

const { name } = bookData;
console.log(name); // ECMAScript 關鍵 30 天

靜態方法

Object.is(value1, value2)

比較兩個值是否相等。回傳布林值。

在 ES5 中,比較兩個值相等需要靠 =====(嚴格等於) 運算子來比較,可是這些運算子各自有些不合理的地方

  • ==: 會自動轉換型別 e.g. 1 == '1' //true
  • ===:
    • NaN不等於自己 e.g. NaN === NaN //false
    • +0 等於 -0 e.g. 0 === -0 //true

因此在 ES2015 中,有在 Object 底下新增一個靜態方法 Object.is 為比較相等提供比較正確的方式。

以下列出在 Object.is 中會回 true 的情況

  • 兩者都是 undefined / null / NaN / true / false / +0 / -0
  • 兩者為完全相等的非零數值 / 字串
  • 兩者參考到同一個物件 / 陣列
const arr = [1, 2, 3];
const _arr1 = arr,
  _arr2 = arr;
const obj = { name: "One Punch Man" };
const _obj1 = obj,
  _obj2 = obj;

Object.is(_arr1, _arr2); //true
Object.is(_obj1, _obj2); //true
Object.is([1, 2, 3], [1, 2, 3]); //false
Object.is({ name: "One Punch Man" }, { name: "One Punch Man" }); //false

Object.assign(target, obj1, obj2, ...)

複製所有傳入物件的可列舉屬性,並合併到一個目標物件中。回傳被合併過後的目標物件。

什麼是可列舉屬性呢? 物件的屬性有分為以下兩種

  • 存在於 prototype: 屬於不可列舉的屬性

    const obj = { name: "One Punch Man" };
    obj.valueOf(); //{ name: "One Punch Man" }
    

    obj 雖然沒有宣告 valueOf 的方法,但是因為在 Objectprototype 中有這個方法。所以繼承 Objectobj 就能使用

  • 存在於實體: 如果沒特別設定,一般屬於可列舉的屬性

    const obj = { name: "One Punch Man", sayHi(){...} };
    obj.sayHi();
    

    我們在 obj 的實體上新增一個方法 sayHi,所以才能直接呼叫 obj.sayHi()

屬性能不能列舉,會影響到一些函式的結果,像是迭代(for...inObject.keys)和 JSON.stringify等。

回到正題,當我們想把一些物件進行合併時,這個方法就能幫助物件進行合併。如果之間有屬性名稱相同時,會以後蓋前的方式取代掉。

要注意的地方是,目標物件同時也會被修改到。如果希望目標物件不被修改到,第一個參數改傳入 {}

const target = { a: 1, b: 2 };
const target1 = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
const returnedTarget1 = Object.assign({}, target, source);
console.log(target); // { a: 1, b: 4, c: 5 }
console.log(target1); // {a: 1, b: 2}

小結

我們發現在 ES2015 中,要處理物件變得輕鬆許多,在物件操作上可以用更少程式來完成複雜的任務。

參考資源


上一篇
ES2015(ES6) - Array
下一篇
ES2015(ES6) - symbol
系列文
從ES到ESNext - 30天輕鬆掌握ECMAScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言